/***
    Amrita ITEWS - Copyright (C) 2009 Amrita Vishwa Vidyapeetham, Amritapuri.
                                       (http://www.amrita.edu)
    ***************************************************************************
    This file is part of the Amrita ITEWS distribution.
    Amrita ITEWS is free software; you can redistribute it and/or modify it 
    under the terms of the GNU General Public License (version 2) as published
    by the Free Software Foundation AND MODIFIED BY the Amrita ITEWS exception.
    ***NOTE*** The exception to the GPL is included to allow you to distribute
    a combined work that includes Amrita ITEWS without being obliged to provide
    the source code for proprietary components outside of the Amrita ITEWS
    software. Amrita ITEWS is distributed in the hope that it will be useful, 
    but WITHOUT ANY WARRANTY; without even the implied warranty of 
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
    Public License for more details. You should have received a copy of the GNU
    General Public License and the Amrita ITEWS license exception along with 
    Amrita ITEWS if not then it can be viewed here: 
    http://itews.amrita.ac.in/license.html.

    Documentation, latest information, license and contact details are at:
    http://itews.amrita.ac.in/

    Amrita ITEWS source code can be found at:
    http://code.google.com/p/itews

    The initial code-base of Amrita ITEWS was developed by Amrita Vishwa 
    Vidyapeetham as part of the project titled,"Intelligent & Interactive 
    Telematics using Emerging Wireless Technologies for Transport Systems 
    (ITEWS)" sponsored by Technology Information Forecasting and Assessment 
    Council (TIFAC), India.
***/

package autopilot;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Hashtable;

import org.knopflerfish.service.log.LogRef;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventAdmin;
import org.osgi.service.event.EventConstants;
import org.osgi.service.event.EventHandler;

public class Activator implements BundleActivator, EventHandler  
{
	private static final String DB_UPDATE_EVENT = "eventTopicToBPSBundle";
	private static final String CURRENT_ROUTE = "currentRoute";
	private static final String CURRENT_NODE ="currentNode";
	private static final String CURRENT_NODE_SEQNO ="currentNodeSeqNo";
	private static final String DETERMINED_NODE_SEQNO_FROM_AUTOPILOT = "determinednodeseqno";
	private static final String NO_NODE ="nonode";
	private static final String NO_ROUTE ="noroute";
	private static final String NEW_MEDIA_SET_ARRIVED = "newMediaSet";
	
	public static BundleContext bc = null;	
	private  LogRef log;
	private ServiceRegistration serviceRegistration; 
	private EventAdmin eventAdmin;
	private AutoPilotConfig config;
	private DBConnectionPool dbConnectionPool ;
	private String currentRouteCode = "";
	private String currentNodeCode = "";
	private String lastNodeCode ="";
	private int currentNodeSeqNo;
	private int previousNodeSeqNo = -1;
	private String autoPilotRouteOne;
	private String autoPilotRouteTwo;
	private String autoPilotSwitch;
	private boolean isVehicleInStartNodeOrEndNode = false;
	private String startNodeOrEndNodeCode = NO_NODE;
	
	private String autoPilotInfoQuery = "SELECT route_schedule_code FROM route_schedules";
	private String routeScheduleNodeAssocQuery = "SELECT node_code FROM route_schedule_node_assoc WHERE route_schedule_code=? ORDER BY node_seq_no";
	private String routeScheduleNodeassocQueryForNodeSeqNo = "SELECT node_seq_no FROM route_schedule_node_assoc WHERE route_schedule_code=? AND node_code=? LIMIT 1";
	private String mediaPlayerQueueDelete = "DELETE FROM media_player_queue";
	private String persistentDataQuery = "SELECT current_route_code, current_node_code,  current_node_seq_no  FROM persistent_data LIMIT 1";
	private String lastMediaPlayedDelete = "DELETE FROM last_media_played";
	private String persistentDataUpdate = "UPDATE persistent_data SET current_node_code=?, current_node_seq_no=?, current_route_code=?, current_trigger_descriptor_id=?";
	private String routeSchedulesQuery = "SELECT usage_count FROM route_schedules WHERE route_schedule_code=?";
	private String routeSchedulesUpdate = "UPDATE route_schedules SET is_current_route='T', usage_count=? WHERE route_schedule_code=?";
	private String routeSchedulesGlobalUpdate = "UPDATE route_schedules SET is_current_route='F'";
	private String startNodeSeqNoQuery = "SELECT MIN(node_seq_no) FROM route_schedule_node_assoc WHERE route_schedule_code=?";
	private String endNodeSeqNoQuery = "SELECT MAX(node_seq_no) FROM route_schedule_node_assoc WHERE route_schedule_code=?";
	
	public void start(BundleContext bc) throws Exception
	{
		Activator.bc = bc;
		log = new LogRef(bc);
		try
		{
			config = AutoPilotConfig.getConfig();
		}
		catch(Exception e)
		{
			log.error(Activator.bc.getBundle().getHeaders().get(Constants.BUNDLE_NAME)+ " failed to start due to configuration file setup error.");
			System.err.println(Activator.bc.getBundle().getHeaders().get(Constants.BUNDLE_NAME)+ " failed to start due to configuration file setup error.");
			Activator.bc = null;
			throw e;
		}
		ServiceReference reference = bc.getServiceReference (EventAdmin.class.getName());
		eventAdmin = (EventAdmin)bc.getService(reference);
		Hashtable ht = new Hashtable();
		ht.put(EventConstants.EVENT_TOPIC, config.getIncomingEvents());
		serviceRegistration = bc.registerService(EventHandler.class.getName(), this, ht);
		autoPilotSwitch = config.getAutoPilotSwitch();
		dbConnectionPool = DBConnectionPool.getInstance(config.getJdbcConnectionURI());
		
		// Set Route for Vehicle Restart
		if (autoPilotSwitch.equals("ON"))
		{
			setRouteForVehicleRestart();
		}
		System.out.println(bc.getBundle().getHeaders().get(Constants.BUNDLE_NAME)+ " started...");
	}
	
	public synchronized void handleEvent(Event event) 
	{
		try
		{
			String eventTopic = event.getTopic();
			if (eventTopic.equals(CURRENT_NODE))
			{
				currentNodeCode = ((String) event.getProperty(CURRENT_NODE)).trim();
				if (currentNodeCode.equals(lastNodeCode))
				{
					log.debug("Same node code arrived in Autopilot. So, not handled");
					return;
				}
				else
				{
					lastNodeCode = currentNodeCode;
				}
				currentNodeSeqNo = (Integer) event.getProperty(CURRENT_NODE_SEQNO);
				log.debug("autopilot: Received current Node "+ currentNodeCode + " current nodeseqno "+currentNodeSeqNo +" previousNodeSeqNo: "+previousNodeSeqNo);
				if (!currentNodeCode.equals(NO_NODE))
				{
					if (autoPilotSwitch.equals("ON"))
					{
						switchToCorrectRouteIfNeeded();
						previousNodeSeqNo = currentNodeSeqNo;
					}
					else
					{
						if (currentNodeSeqNo <= previousNodeSeqNo)
						{
							currentNodeSeqNo = -1;
							currentNodeCode = "";
							currentRouteCode = NO_ROUTE;
							publishAutoPilotRouteSetting();
							previousNodeSeqNo = currentNodeSeqNo;
						}
					}
				}
				else
				{
					if (isVehicleInStartNodeOrEndNode == true)
					{
						isVehicleInStartNodeOrEndNode = false;
						log.debug("autopilot: Setting route if required when bus leaves start node");
						setRouteOnlyForTripStart(startNodeOrEndNodeCode);
						previousNodeSeqNo = currentNodeSeqNo;
					}
				}
			}
			else if (eventTopic.equals(CURRENT_ROUTE))
			{
				currentRouteCode = ((String) event.getProperty(CURRENT_ROUTE)).trim();
				log.debug("autopilot: Received CURRENT route: "+ currentRouteCode);
			}
			else if (eventTopic.equals(DB_UPDATE_EVENT))
			{
				if (autoPilotSwitch.equals("ON"))
				{
					setRouteIfNewRoutesAreAddedFromTCM();
				}
			}
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}
	
	private void switchToCorrectRouteIfNeeded()
	{
		if (getStartNodeForCurrentRoute() == currentNodeSeqNo || getEndNodeForCurrentRoute() == currentNodeSeqNo)
		{
			isVehicleInStartNodeOrEndNode = true;
			startNodeOrEndNodeCode = currentNodeCode;
			log.debug("autopilot: isVehicleInStartNodeOrEndNode set to true");
		}
		else if (currentNodeSeqNo <= previousNodeSeqNo)
		{
			if (autoPilotRouteOne == null || autoPilotRouteOne.equals("") || autoPilotRouteTwo == null || autoPilotRouteTwo.equals(""))
			{
				log.debug("autopilot: Switched to NO_ROUTE . Since no other route in table to switch to.");
				currentNodeSeqNo = -1;
				currentNodeCode = "";
				currentRouteCode = NO_ROUTE;
				publishAutoPilotRouteSetting();
				return;
			}
			
			if (currentRouteCode.equals(autoPilotRouteOne))
			{
				log.debug("autopilot: Switched to 2nd route! "+" currentNodeSeqNo :"+ currentNodeSeqNo + " lastNodeSeqNo: "+previousNodeSeqNo );
				currentRouteCode = autoPilotRouteTwo;
			}
			else
			{
				log.debug("autopilot: Switched to 1st route! "+" currentNodeSeqNo :"+ currentNodeSeqNo + " lastNodeSeqNo: "+previousNodeSeqNo );
				currentRouteCode = autoPilotRouteOne;
			}
			// Here we SHOULD NOT set the node seq no to zero since the vehicle could be on any node on the rote
			currentNodeSeqNo = getNodeSeqNoForNewRoute(currentRouteCode);
			log.debug("currentNodeSeqNo obtained for the newly switched route :"+currentNodeSeqNo);
			publishAutoPilotRouteSetting();
			notifyDeterminedNodeSeqNoWhenRouteSwitched(currentNodeSeqNo);
		}
	}
	
	private void setRouteOnlyForTripStart(String nodeCode)
	{
		if (autoPilotRouteOne != null && !autoPilotRouteOne.equals(""))
		{
			boolean nodeIsFirstNodeOfRoute = checkIfNodeIsFirstNodeOfRoute(autoPilotRouteOne, nodeCode);
			log.debug("autopilot: isnodeIsFirstNodeOfRouteOne : "+nodeIsFirstNodeOfRoute);
			if (nodeIsFirstNodeOfRoute == true)
			{
				currentNodeSeqNo = 0;
				if (!currentRouteCode.equals(autoPilotRouteOne))
				{
					currentRouteCode = autoPilotRouteOne;
					publishAutoPilotRouteSetting();
					notifyDeterminedNodeSeqNoWhenRouteSwitched(currentNodeSeqNo);
				}
				return;
			}
		}
		if (autoPilotRouteTwo != null && !autoPilotRouteTwo.equals(""))
		{
			boolean nodeIsFirstNodeOfRoute = checkIfNodeIsFirstNodeOfRoute(autoPilotRouteTwo, nodeCode);
			log.debug("autopilot: isnodeIsFirstNodeOfRouteTwo : "+nodeIsFirstNodeOfRoute);
			if (nodeIsFirstNodeOfRoute == true)
			{
				currentNodeSeqNo = 0;
				if (!currentRouteCode.equals(autoPilotRouteTwo))
				{
					currentRouteCode = autoPilotRouteTwo;
					publishAutoPilotRouteSetting();
					notifyDeterminedNodeSeqNoWhenRouteSwitched(currentNodeSeqNo);
				}
				return;
			}
		}
	}
	
	private void setRouteIfNewRoutesAreAddedFromTCM()
	{
		Connection conn = null;
		PreparedStatement preparedStmt = null;
		ResultSet rs = null;
		try
		{
			conn = dbConnectionPool.getConnection();
			preparedStmt = dbConnectionPool.getPreparedStmt(conn, autoPilotInfoQuery);
			rs = preparedStmt.executeQuery();
			if (rs.next() == true)
			{
				autoPilotRouteOne =  rs.getString(1);
			}
			if (rs.next() == true)
			{
				autoPilotRouteTwo = rs.getString(1);
			}

			if  (autoPilotRouteOne == null || autoPilotRouteOne.trim().equals(""))
			{
				currentRouteCode = NO_ROUTE;
				currentNodeSeqNo = -1;
			}
			else
			{
				currentRouteCode = autoPilotRouteOne;
				currentNodeSeqNo = 0;
			}
			currentNodeCode = "";
			publishAutoPilotRouteSetting();
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		finally
		{
			if (rs != null)
			{
				try {rs.close();} catch (SQLException e) {} 
				rs = null;
			}
			if (preparedStmt != null)
			{
				try {preparedStmt.close();} catch (SQLException e) {} 
				preparedStmt = null;
			}
			if (conn != null)
			{
				try {conn.close();} catch (SQLException e) {}
				conn = null;
			}
		}
	}
	
	private void setRouteForVehicleRestart()
	{
		Connection conn = null;
		PreparedStatement preparedStmt = null;
		ResultSet rs = null;
		try
		{
			conn = dbConnectionPool.getConnection();
			preparedStmt = dbConnectionPool.getPreparedStmt(conn, autoPilotInfoQuery);
			rs = preparedStmt.executeQuery();
			if (rs.next() == true)
			{
				autoPilotRouteOne =  rs.getString(1);
			}
			if (rs.next() == true)
			{
				autoPilotRouteTwo = rs.getString(1);
			}
			
			//Get first from Persistent Data
			setCurrentRouteUsingPersistentData();

			if (currentRouteCode.equals(NO_ROUTE))
			{
				if (autoPilotRouteOne == null || autoPilotRouteOne.trim().equals(""))
				{
					currentRouteCode = NO_ROUTE;
					currentNodeSeqNo = -1;
				}
				else
				{
					currentRouteCode = autoPilotRouteOne;
					currentNodeSeqNo = 0;
				}
				currentNodeCode = "";
				publishAutoPilotRouteSetting();
			}
			else
			{
				setRouteOnlyForTripStart(currentNodeCode);
			}
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		finally
		{
			if (rs != null)
			{
				try {rs.close();} catch (SQLException e) {} 
				rs = null;
			}
			if (preparedStmt != null)
			{
				try {preparedStmt.close();} catch (SQLException e) {} 
				preparedStmt = null;
			}
			if (conn != null)
			{
				try {conn.close();} catch (SQLException e) {}
				conn = null;
			}
		}
	}
	
	private void setCurrentRouteUsingPersistentData()
	{
		Connection conn = null;
		PreparedStatement preparedStmt = null;
		ResultSet rs = null;
		try
		{
			conn = dbConnectionPool.getConnection();
			preparedStmt = dbConnectionPool.getPreparedStmt(conn, persistentDataQuery);
			rs = preparedStmt.executeQuery();
			if (rs.next() == true)
			{
				currentRouteCode = rs.getString(1);
				currentNodeCode = rs.getString(2);
				currentNodeSeqNo = rs.getInt(3);
			}
			else
			{
				currentRouteCode = NO_ROUTE;
			}
			log.debug("autopilot: From persistent data: RouteCode "+currentRouteCode + "Node: "+currentNodeCode + "seq no "+currentNodeSeqNo);
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		finally
		{
			if (rs != null)
			{
				try {rs.close();} catch (SQLException e) {} 
				rs = null;
			}
			if (preparedStmt != null)
			{
				try {preparedStmt.close();} catch (SQLException e) {} 
				preparedStmt = null;
			}
			if (conn != null)
			{
				try {conn.close();} catch (SQLException e) {}
				conn = null;
			}
		}
	}
	
	private int getNodeSeqNoForNewRoute(String routeCode)
	{
		Connection conn = null;
		PreparedStatement preparedStmt = null;
		ResultSet rs = null;
		int seqNo = 0;
		try
		{
			conn = dbConnectionPool.getConnection();
			preparedStmt = dbConnectionPool.getPreparedStmt(conn, routeScheduleNodeassocQueryForNodeSeqNo);
			preparedStmt.setString(1, routeCode);
			preparedStmt.setString(2, currentNodeCode);
			rs = preparedStmt.executeQuery();
			if (rs.next() == true)
			{
				seqNo = rs.getInt(1);
			}
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		finally
		{
			if (rs != null)
			{
				try {rs.close();} catch (SQLException e) {} 
				rs = null;
			}
			if (preparedStmt != null)
			{
				try {preparedStmt.close();} catch (SQLException e) {} 
				preparedStmt = null;
			}
			if (conn != null)
			{
				try {conn.close();} catch (SQLException e) {}
				conn = null;
			}
		}
		return seqNo;
	}
	
	private int getStartNodeForCurrentRoute()
	{
		Connection conn = null;
		PreparedStatement preparedStmt = null;
		ResultSet rs = null;
		int startNodeSeqNo = -999;
		try
		{
			conn = dbConnectionPool.getConnection();
			preparedStmt = dbConnectionPool.getPreparedStmt(conn, startNodeSeqNoQuery);
			preparedStmt.setString(1, currentRouteCode);
			rs = preparedStmt.executeQuery();
			if (rs.next() == true)
			{
				startNodeSeqNo = rs.getInt(1);
			}
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		finally
		{
			if (rs != null)
			{
				try {rs.close();} catch (SQLException e) {} 
				rs = null;
			}
			if (preparedStmt != null)
			{
				try {preparedStmt.close();} catch (SQLException e) {} 
				preparedStmt = null;
			}
			if (conn != null)
			{
				try {conn.close();} catch (SQLException e) {}
				conn = null;
			}
		}
		return startNodeSeqNo;
	}
	
	private int getEndNodeForCurrentRoute()
	{
		Connection conn = null;
		PreparedStatement preparedStmt = null;
		ResultSet rs = null;
		int endNodeSeqNo = -999;
		try
		{
			conn = dbConnectionPool.getConnection();
			preparedStmt = dbConnectionPool.getPreparedStmt(conn, endNodeSeqNoQuery);
			preparedStmt.setString(1, currentRouteCode);
			rs = preparedStmt.executeQuery();
			if (rs.next() == true)
			{
				endNodeSeqNo = rs.getInt(1);
			}
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		finally
		{
			if (rs != null)
			{
				try {rs.close();} catch (SQLException e) {} 
				rs = null;
			}
			if (preparedStmt != null)
			{
				try {preparedStmt.close();} catch (SQLException e) {} 
				preparedStmt = null;
			}
			if (conn != null)
			{
				try {conn.close();} catch (SQLException e) {}
				conn = null;
			}
		}
		return endNodeSeqNo;
	}
	
	private boolean checkIfNodeIsFirstNodeOfRoute(String routeCode, String nodeCode)
	{
		Connection conn = null;
		PreparedStatement preparedStmt = null;
		ResultSet rs = null;
		try
		{
			conn = dbConnectionPool.getConnection();
			preparedStmt = dbConnectionPool.getPreparedStmt(conn, routeScheduleNodeAssocQuery);
			preparedStmt.setString(1, routeCode);
			rs = preparedStmt.executeQuery();
			if (rs.next() == true)
			{
				String firstNodeOfRoute = rs.getString(1);
				if (firstNodeOfRoute.equals(nodeCode))
				{
					return true;
				}
				else
				{
					return false;
				}
			}
			else
			{
				return false;
			}
		}
		catch(Exception e)
		{
			e.printStackTrace();
			return false;
		}
		finally
		{
			if (rs != null)
			{
				try {rs.close();} catch (SQLException e) {} 
				rs = null;
			}
			if (preparedStmt != null)
			{
				try {preparedStmt.close();} catch (SQLException e) {} 
				preparedStmt = null;
			}
			if (conn != null)
			{
				try {conn.close();} catch (SQLException e) {}
				conn = null;
			}
		}
	}
	
	private void publishAutoPilotRouteSetting()
	{
		Connection conn = null;
		PreparedStatement preparedStmt = null;
		PreparedStatement preparedStmt1 = null;
		PreparedStatement preparedStmt2 = null;
		PreparedStatement preparedStmt2A = null;
		ResultSet rs = null;
		try
		{
			String lastRouteCode = "";
			conn = dbConnectionPool.getConnection();
			preparedStmt = dbConnectionPool.getPreparedStmt(conn, persistentDataQuery);
			rs = preparedStmt.executeQuery();
			if (rs.next() == true)
			{
				lastRouteCode = rs.getString(1).trim();
			}
			rs.close();
			rs = null;
			preparedStmt.close();
			preparedStmt = null;
			if (lastRouteCode != null && !lastRouteCode.equals(currentRouteCode))
			{
				int usage_count = 0;
				preparedStmt = dbConnectionPool.getPreparedStmt(conn, routeSchedulesQuery);
				preparedStmt.setString(1, currentRouteCode);
				rs = preparedStmt.executeQuery();
				if (rs.next() == true)
				{
					usage_count = rs.getInt(1);
				}
				rs.close();
				rs = null;
				preparedStmt.close();
				preparedStmt = null;
				
				preparedStmt1 = dbConnectionPool.getPreparedStmt(conn, routeSchedulesGlobalUpdate);
				preparedStmt1.executeUpdate();
				preparedStmt1.close();
				preparedStmt1 = null;
				
				preparedStmt1 = dbConnectionPool.getPreparedStmt(conn, routeSchedulesUpdate);
				preparedStmt1.setInt(1, ++usage_count);
				preparedStmt1.setString(2, currentRouteCode);
				preparedStmt1.executeUpdate();
				preparedStmt1.close();
				preparedStmt1 = null;
				
				log.debug("updating persistent data with route code: " +currentRouteCode + " NodeSeqNo: " +currentNodeSeqNo + "node code: "+currentNodeCode);
				preparedStmt1 = dbConnectionPool.getPreparedStmt(conn, persistentDataUpdate);
				preparedStmt1.setString(1, currentNodeCode);
				preparedStmt1.setInt(2, currentNodeSeqNo);
				preparedStmt1.setString(3, currentRouteCode);
				preparedStmt1.setInt(4, 0);
				preparedStmt1.executeUpdate();
				preparedStmt1.close();
				preparedStmt1 = null;
				
				preparedStmt2 = dbConnectionPool.getPreparedStmt(conn, mediaPlayerQueueDelete);
				preparedStmt2.executeUpdate();
				preparedStmt2.close();
				preparedStmt2 = null;
				
				preparedStmt2A = dbConnectionPool.getPreparedStmt(conn, lastMediaPlayedDelete);
				preparedStmt2A.executeUpdate();
				preparedStmt2A.close();
				preparedStmt2A = null;
				
				Hashtable routeInfo = new Hashtable();
				routeInfo.put(CURRENT_ROUTE, currentRouteCode.trim());
				Event event = new Event(CURRENT_ROUTE, routeInfo);
				this.eventAdmin.postEvent(event);
				log.info("Published new RouteCode from autopilot: " +currentRouteCode);
				
				//Notify Media Player Manager regarding the route change
				Hashtable newMediaSetArrivalInfo = new Hashtable();
				event = new Event(NEW_MEDIA_SET_ARRIVED, newMediaSetArrivalInfo);
				this.eventAdmin.postEvent(event);
			}
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		finally
		{
    		if (rs != null)
    		{
    			try {rs.close();} catch (SQLException e) {} 
    			rs = null;
    		}
			if (preparedStmt != null)
    		{
    			try {preparedStmt.close();} catch (SQLException e) {} 
    			preparedStmt = null;
    		}
			if (preparedStmt1 != null)
    		{
    			try {preparedStmt1.close();} catch (SQLException e) {} 
    			preparedStmt1 = null;
    		}
    		if (preparedStmt2 != null)
    		{
    			try {preparedStmt2.close();} catch (SQLException e) {} 
    			preparedStmt2 = null;
    		}
      		if (preparedStmt2A != null)
    		{
    			try {preparedStmt2A.close();} catch (SQLException e) {} 
    			preparedStmt2A = null;
    		}
			if (conn != null)
			{
				try {conn.close();} catch (SQLException e) {}
				conn = null;
			}
		}
	}
	
	private void notifyDeterminedNodeSeqNoWhenRouteSwitched(int seqNo) 
	{
		Hashtable nodeInfo = new Hashtable();
		nodeInfo.put(CURRENT_NODE, currentNodeCode.trim());
		nodeInfo.put(CURRENT_NODE_SEQNO, seqNo);
		Event event = new Event(DETERMINED_NODE_SEQNO_FROM_AUTOPILOT, nodeInfo);
		this.eventAdmin.postEvent(event);
		log.info("autopilot: Published Determined Node Seq No for Node Code:" +currentNodeCode);
	}
	
	public void stop(BundleContext context) throws Exception 
	{
		if (serviceRegistration!=null)
		{
			serviceRegistration.unregister();
			serviceRegistration = null;
		}
		System.out.println(bc.getBundle().getHeaders().get(Constants.BUNDLE_NAME)+ " stopped!");
		Activator.bc = null;
	}
}
